project(shape)

# Get information on directories from qmake
# as this is not yet exported by cmake.
# Used for QT_INSTALL_DOCS
function(qt5_query_qmake)
    if(NOT TARGET Qt::qmake)
        message(FATAL_ERROR "Qmake was not found. Add find_package(Qt5 COMPONENTS Core) to CMake to enable.")
    endif()

    # dummy check for if we already queried qmake
    if(QT_INSTALL_BINS)
        return()
    endif()

    get_target_property(_qmake_binary Qt::qmake IMPORTED_LOCATION)
    execute_process(COMMAND "${_qmake_binary}" "-query"
        TIMEOUT 10
        RESULT_VARIABLE _qmake_result
        OUTPUT_VARIABLE _qmake_stdout
        OUTPUT_STRIP_TRAILING_WHITESPACE
        COMMAND_ERROR_IS_FATAL ANY
    )

    if(NOT "${_qmake_result}" STREQUAL "0")
        message(FATAL_ERROR "Qmake did not execute successfully: ${_qmake_result}.")
    endif()

    # split into lines:
    string(REPLACE "\n" ";" _lines "${_qmake_stdout}")

    foreach(_line ${_lines})
        # split line into key/value pairs
        string(REPLACE ":" ";" _parts "${_line}")
        list(GET _parts 0 _key)
        list(REMOVE_AT _parts 0)
        string(REPLACE ";" ":" _value "${_parts}")

        set("${_key}" "${_value}" CACHE PATH "qmake import of ${_key}" FORCE)
    endforeach()
endfunction()

function(_setup_qdoc_targets _qdocconf_file _retval)
    set(options)
    set(oneValueArgs HTML_DIR INSTALL_DIR POSTFIX)
    set(multiValueArgs INDEXES INCLUDE_DIRECTORIES FRAMEWORK_PATHS ENVIRONMENT_EXPORTS)
    cmake_parse_arguments(_arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    foreach(_index ${_arg_INDEXES})
        list(APPEND _qdoc_index_args "-indexdir;${_index}")
    endforeach()

    set(_env "")

    foreach(_export ${_arg_ENVIRONMENT_EXPORTS})
        if(NOT DEFINED "${_export}")
            message(FATAL_ERROR "${_export} is not known when trying to export it to qdoc.")
        endif()

        list(APPEND _env "${_export}=${${_export}}")
    endforeach()

    set(_full_qdoc_command "${QT_QDOC_EXECUTABLE}")

    if(_env)
        set(_full_qdoc_command "${CMAKE_COMMAND}" "-E" "env" ${_env} "${QT_QDOC_EXECUTABLE}")
    endif()

    if(_arg_HTML_DIR STREQUAL "")
        set(_arg_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc")
    endif()

    get_filename_component(_target "${_qdocconf_file}" NAME_WE)

    set(_html_outputdir "${_arg_HTML_DIR}/${_target}${_arg_POSTFIX}")
    file(MAKE_DIRECTORY "${_html_outputdir}")

    set(_qdoc_include_args "")

    if(_arg_INCLUDE_DIRECTORIES OR _arg_FRAMEWORK_PATHS)
        # pass include directories to qdoc via hidden @ option, since we need to generate a file
        # to be able to resolve the generators inside the include paths
        set(_qdoc_includes "${CMAKE_CURRENT_BINARY_DIR}/cmake/qdoc_${_target}.inc")
        set(_qdoc_include_args "@${_qdoc_includes}")
        set(_includes "")

        if(_arg_INCLUDE_DIRECTORIES)
            set(_includes "-I$<JOIN:${_arg_INCLUDE_DIRECTORIES},\n-I>\n")
        endif()

        set(_frameworks "")

        if(_arg_FRAMEWORK_PATHS)
            set(_frameworks "-F$<JOIN:${_arg_FRAMEWORK_PATHS},\n-F>\n")
        endif()

        file(GENERATE
            OUTPUT "${_qdoc_includes}"
            CONTENT "${_includes}${_frameworks}"
        )
    endif()

    set(_html_target "html_docs_${_target}")
    add_custom_target("${_html_target}"
        ${_full_qdoc_command} -outputdir "${_html_outputdir}" "${_qdocconf_file}"
        ${_qdoc_index_args} ${_qdoc_include_args}
        COMMENT "Build HTML documentation from ${_qdocconf_file}"
        DEPENDS "${_qdocconf_file}"
        SOURCES "${_qdocconf_file}"
        WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
        VERBATIM
    )

    # add_dependencies(html_docs "${_html_target}")

    # # Install HTML files as a special component
    if(_arg_INSTALL_DIR)
        install(DIRECTORY "${_html_outputdir}" DESTINATION "${_arg_INSTALL_DIR}"
            COMPONENT html_docs EXCLUDE_FROM_ALL
        )
    endif()

    set("${_retval}" "${_html_outputdir}" PARENT_SCOPE)
endfunction()

message("QT_INSTALL_BINS: ${QT_INSTALL_BINS}")

find_package(QT NAMES Qt6 Qt5 COMPONENTS Core DocTools REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core DocTools REQUIRED)

message("QT_INSTALL_BINS: ${QT_INSTALL_BINS}")

file(GLOB _src *.h *.cpp)
add_library(${PROJECT_NAME} STATIC ${_src})

if(NOT TARGET Qt${QT_VERSION_MAJOR}::qdoc)
    message(FATAL_ERROR "qdoc target not found")
endif()

get_target_property(QT_QDOC_EXECUTABLE Qt${QT_VERSION_MAJOR}::qdoc IMPORTED_LOCATION)

message("QT_INSTALL_BINS: ${QT_INSTALL_BINS}")

qt5_query_qmake()

set(QT_VER "${QT_VERSION}" CACHE STRING "qt version alias" FORCE)

if(APPLE)
    # version-less target Qt::Core is an interface library that links to QtX::Core
    get_target_property(_qt_core Qt::Core INTERFACE_LINK_LIBRARIES)
    get_target_property(_qt_target ${_qt_core} LOCATION) # <fw_path>/QtCore.framework/QtCore
    get_filename_component(_qt_loc "${_qt_target}" DIRECTORY)
    set(_framework_paths FRAMEWORK_PATHS "${_qt_loc}/..")
else()
    set(_framework_paths)
endif()

set(QDOC_INDEX_DIR "${QT_INSTALL_DOCS}")

_setup_qdoc_targets(shape.qdocconf _html_outputdir
    HTML_DIR "${CMAKE_BINARY_DIR}/html"
    INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
    INDEXES ${QT_INSTALL_DOCS} ${QDOC_INDEX_DIR}
    ENVIRONMENT_EXPORTS QT_INSTALL_DOCS QDOC_INDEX_DIR QT_VERSION QT_VER
    POSTFIX "1"
    INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}
    ${_framework_paths}
)